# -*- coding: utf-8 -*-
"""
TODO : rewrite the whole code and the comment

structure analysis based on lyric only by finding repetition

the basic problem : what is the structure of a lyric, from a larger scale view
or smaller view the result may be different
"""

from Lyric import Lyric
from common_func import _sen_similar,print_seg,_insertlist,similarthres
from suffix_tree_substring import get_frequent_common,get_common_length
import re,copy

import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)

sadebug = False
sa1debug = False

def lmc_analysis(lyric):
    """
    lryic max common segment recognition
    """
    linelist = lyric.getlinelist()
    return _ana1(linelist)


def _ana1(linelist):
    """
    use the suffix array for the longest repeated substring finding
    """
    # TODO this function is too long

    bitnum = 2

    # create the suffix structure for comparison
    name_list = range(len(linelist))
    for i in range(1,len(linelist)):
        for j in range(i):
            if linelist[i]['content'] == linelist[j]['content']:
                name_list[i] = name_list[j]
                break

    # TODO change name? 
    # index_name_list seem to be used for the sub string record
    name_str = ""
    index_name_list = []
    for i,n in enumerate(name_list):
        name_str += "%02d"%(n) # TODO change with bitnum here
        index_name_list.append( (i,n) )
        #print n,linelist[i]['content'].decode('utf-8')#,index_name_list_list
    index_name_list_list = [ index_name_list ]

    seg_list = []
    iter_num = 0
    while True:

        # TODO this is for debug
        iter_num += 1
        #print "### begin of iter %d ###"%(iter_num)
        #print index_name_list_list info
        #print 'index name list list'
        for index_name_list in index_name_list_list:
            begin_index = index_name_list[0][0]
            end_index = index_name_list[-1][0]+1  #end_index is the number after
            #print name_str[begin_index*bitnum:end_index*bitnum]

        
        # build the suffix array for each of the index_name_list
        suffix_array = []
        for index_name_list in index_name_list_list:
            begin_index = index_name_list[0][0]
            end_index = index_name_list[-1][0]+1  #end_index is the number after

            # for each substring structure, create the suffix array for it
            for i in range(begin_index,end_index):
                suffix_array.append(
                        (i, end_index, name_str[i*bitnum:end_index*bitnum]) )
                #print 'add suffix',suffix_array[-1]
        suffix_array.sort( lambda x,y:cmp(x[2],y[2]) )


        # get the largest common substring
        #print len(suffix_array)
        #for sa in suffix_array:
        #    print sa

        
        # after get the longest common string, 
        # rebuild the index_name_list_list, store the new structure
        # TODO trying, use the length*freq as the criter
        max_len = -1
        sub_str = ""
        for i in range( len(suffix_array)-1 ):
            # compare with i+1
            start1 = suffix_array[i][0]
            start2 = suffix_array[i+1][0]
            com_len = get_common_length( 
                    suffix_array[i][2], suffix_array[i+1][2] ,
                    start1*2 , start2*2)

            tmp_str = suffix_array[i][2][:com_len]
            count = 0
            for index_name_list in index_name_list_list:
                begin_index = index_name_list[0][0]
                end_index = index_name_list[-1][0]+1  #end_index is the number after
                sub_seg_str = name_str[begin_index*bitnum:end_index*bitnum]
                count += sub_seg_str.count(tmp_str)
            weight = com_len * count
            # TODO change this weight
            #print 'aaa',suffix_array[i],suffix_array[i+1],
            #print tmp_str,com_len,count

            # TODO this is the debug part
            #if com_len > max_len:
            #    max_len = com_len
            if weight > max_len:
                max_len = weight
                sub_str = suffix_array[i][2][:com_len]
                #print max_len,sub_str,suffix_array[i][2],suffix_array[i+1][2],\
                #        start1*2,start2*2


        #print 'best sub str',sub_str
        # get the real sub
        # not found the best match, then break
        if len(sub_str) < 3*bitnum:
            raise Exception('max common is less than 3 lines')

        #TODO here can return
        # find the index of current 
        m = re.search( sub_str, name_str )
        return [ m.start() / bitnum , m.end() / bitnum -1]
        
if __name__ == "__main__":
    #c = get_common_length("1819200910111200010203181920091011120910111209101112","181920091011120910111209101112",36,58)
    #a = "1819200910111200010203181920091011120910111209101112"
    #print c,a[:c]
    #print get_frequent_common(["0001020304050607080910111213141516171819200910111200010203181920091011120910111209101112"],2)
    #exit()
    
    l = Lyric()
    #fname = "harrybobo.lrc"
    #fname = "wangfei.txt"
    fname = "she-toodetail.lrc"
    l.loadfile(fname)
    linelist = l.getlinelist()

    for i,line in enumerate(linelist):
        #print i,str(line['time'])+":"+line['content'].decode('utf-8')
        a = 1

    segs = lmc_analysis(l)
    print segs
    for i,line in enumerate(linelist):
        if i >= segs[0] and i <= segs[1]:
            print line['content']
    #printseg(linelist,segs)

